⌂ HOME
AI VAULT  /  Cx Skill Map  /  Built Skills  /  BAS & Controls  /  Build SOO Guide
SKILL FLOW · DWG-02 · 05/26/2026
SKILL FLOW · START → FINISH

Build SOO
Guide

Build a UNVC SOO (Sequence of Operation) Verification workbook for any UNVC project from its mechanical specs. One .xlsx with a Project header tab plus one tab per equipment unit, each tab containing test blocks that walk a field-test agent through verifying every sequence, setpoint, alarm, and interlock the project's controls specification mandates.

BUILT · v1 COMPLEXITY ●●●●● 5/5 PHASE · BAS & CONTROLS CROSS-PHASE HUB SKILL ID · soo-creation-cowork
Trigger

Field-Test Agent or PM Calls the Skill

User points to a project folder under <owner>'s Projects - General\<Project Name>\ and asks to "create the SOO" or "build the SOO checklist." Project must be at the commissioning-prep stage where 0-Checklists/ is being populated. Cowork session and project folder both must be mounted via request_cowork_directory before any I/O.

01
PHASE I · SOURCE ACQUISITION

Locate the Controls Spec

Walk the project's contract-documents tree in priority order. Vendor submittals beat design specs; design specs beat combined drawing sets. Stop at the first source found.

  1. <Project>/11-Controls/ — controls submittal (Verasys, Niagara, ALC, Distech, Tracer). Richer on sequences than the design spec when present.
  2. <Project>/000-Contract Documents/Specifications/Mechanical Specs.pdf — the design controls spec. Most common source.
  3. <Project>/000-Contract Documents/Conformed/<combined>.pdf — combined A/M/P/E set. Large (>100 MB); fallback only.
◆ Gate · File reachable?
Check for OneDrive cloud-only stubs — file size > 0 but stat → Blocks: 0 means the file isn't on disk.
YES → continue

Hand the local path to Step 02.

NO → pause & ask

Tell user: right-click the file in File Explorer → "Always keep on this device". Don't try alternative fetch paths.

Inputs Project folder path Outputs Local PDF path
02
PHASE I · SOURCE ACQUISITION

Extract Spec Text (OCR if Needed)

Most UNVC mechanical specs are image-based scans. Sample-check the text layer before committing to an OCR pass that costs ~3 minutes per 86-page spec.

  1. Open the PDF with pdfplumber and extract text from the middle page as a probe.
  2. If len(sample) ≥ 50 per sampled page → text-extractable. Use pdfplumber or pdftotext -layout. Skip to Step 03.
  3. If image-based → OCR via the bundled scripts/ocr_spec.py. Two-pass: low-DPI (-r 150 -gray) full-spec scan to locate the SOO section, then high-DPI (-r 250) on identified pages for numeric accuracy.
◆ Gate · Has text layer?
YES → fast path

Cheap text extraction. ~5 sec for 86 pages.

NO → OCR required

pdftoppmtesseract with xargs -P 4. ~3 min for 86 pages.

⚑ Known quirk · OCR latency
pdfplumber.extract_text() returns empty strings page after page on scanned PDFs. Always sample-check first — if first three sampled pages return >50 chars each, the PDF has a text layer and you can skip OCR.
Script scripts/ocr_spec.py Output ocr/page-*.txt
03
PHASE II · TARGETING

Find the SOO Section

The behavioral rules live under PART 3 — EXECUTION → §3.2 SEQUENCE OF OPERATION of the controls specification section. Identify the page range (typically 4–8 pages); everything downstream works from these pages only.

Search headers in priority order:

  1. SECTION 23 09 33 — Sequence of Operation (primary)
  2. SECTION 23 09 23 — Direct Digital Control (DDC) for HVAC
  3. SECTION 23 09 13 — Instrumentation and Control Devices for HVAC
  4. SECTION 23 09 00 — Instrumentation and Control for HVAC
  5. SECTION 25 95 00 — Integrated Automation Control Sequences
  6. SECTION 25 90 00 — Integrated Automation Sequence of Operations
  7. Legacy MasterFormat fallback: Section 15900 / 15915
⚑ Fallback search
When section numbers don't match, grep the OCR for the header text:
grep -liE "sequence of operation|3\.2 SEQUENCE|electric and electronic control" ocr/page-*.txt
Output SOO page range (e.g. 28–33)
04
PHASE II · TARGETING

Identify Equipment Groups

Read the SOO text, list every equipment tag mentioned, and group by UNVC convention. The spec drives grouping — identical sequences share a tab; any sequence difference splits.

  1. Same-tag families with identical sequences → one tab. P-1 and P-2 (paired hydronic pumps) → tab P-1 P-2 Pumps. EF-1, EF-2, EF-10 on the same schedule → tab EF-1 EF-2 EF-10.
  2. Class-level sequences → one tab per class. All VAV terminals → VAV Terminals. Don't make 25 zone tabs.
  3. Distinct sequences → separate tabs. RT-1 with economizer vs RT-2 without → split.
  4. One-off equipment → its own tab. B-1 Boiler, CV-1 ERV, AC-1 Heat Pump.
  5. Equipment mentioned without controls content → no tab. Surface in the user summary as "verify whether commissioning testing is needed."
⚑ Excel sheet-name constraints
Max 31 chars · forbidden: / \ ? * [ ] · forbidden first/last: apostrophe · case-insensitive uniqueness. P-1/P-2 Pumps won't save — write P-1 P-2 Pumps. If too long, abbreviate the class label, not the tags.
Reference references/equipment-grouping.md Output Equipment groups · tab names
05
PHASE III · CONTENT EXTRACTION

Apply the Strict Source Rule

The single most important rule of the skill: every test block must trace back to text in the spec. No inferred sequences. No "typical HVAC behaviors" from training data. No boilerplate filler. If the spec doesn't say it, it doesn't go in the workbook. Gaps are surfaced to the user, not invented.

For each equipment group, write one test block per distinct mode, sequence, alarm, setpoint, or interlock explicitly described in the SOO text. Each block has four lines:

  1. Mode — short label of what's being verified · e.g. Building Schedule (Occupied / Unoccupied)
  2. Operation — one sentence summarizing the spec's stated behavior
  3. Task — 1–3 sentences, active voice, what the field-test agent does. No instruments mentioned — we test behavior, not calibration.
  4. Expected result — what the agent observes if the system runs per spec
⛔ Rejected · do NOT include
Lead/lag tests when the spec only says "either pump shall run continuously." · Freeze-stat tests when the spec is silent. · Numeric thresholds the spec doesn't quantify (write the test qualitatively instead).
⚑ Excluded from SOO scope
Surface but exclude from workbook: §3.3 Field Quality Control (calibration), §3.4 System Startup (zone naming, holidays, clock), §3.5 Adjusting (programming memory), §3.6 Closeout / Owner Training. These belong in the Contractor Readiness checklist, not the SOO.
06
PHASE IV · ASSEMBLY

Build the Workbook

Hand the equipment-groups dict + test blocks to scripts/build_soo.py. The script does the openpyxl heavy-lifting — one template clone per group, populate, save.

  1. Load assets/Template.xlsx (or the path in UNVC_SOO_TEMPLATE env override).
  2. Copy the Equipment 1 placeholder once per equipment group BEFORE populating any sheet. Populating in place and then copying inherits the populated state — cross-tab contamination is a real, observed bug.
  3. Rename each copy to its equipment group's tab name (apply the 31-char + forbidden-character rules).
  4. Populate row 1 (title), row 2 (context — manufacturer, BAS topology, key setpoints), and test blocks from row 4 down (4 rows per block: Mode 22pt / Operation 32pt / Task 60pt / Expected 48pt).
  5. Remove the original Equipment 1 placeholder.
  6. Populate the Project sheet: name in A1, subtitle in A2, metadata (Builder/Developer, FT Agent, Date, Project Name) in rows 4–5, hyperlinked equipment index from row 7 onward.
⚑ Known quirk · cross-tab contamination
openpyxl.copy_worksheet() copies the source sheet's current contents — not the empty template. Always clone ALL tabs from the empty template first, then populate.
⚑ Hyperlink storage
Use Hyperlink(ref=…, location="'TabName'!A1", display=…) — stores in the canonical location attribute (internal link). Avoid cell.hyperlink = "#'Tab'!A1" which Excel treats as external.
Script scripts/build_soo.py Template assets/Template.xlsx Library override $UNVC_SOO_TEMPLATE
07
PHASE V · QUALITY CONTROL

Two-Round QC Pass

After the workbook saves, two QC passes — one mechanical, one independent. The independent reviewer never sees the build code, only the source spec and the populated workbook.

ROUND 1 · MECHANICAL
scripts/qc_workbook.py
  • File opens in formula + data-only modes
  • Sheet names + order match equipment list
  • No leftover Equipment 1 placeholder
  • Every block: Mode / Operation / Task / Expected result, in order
  • No formula errors (#REF!, #DIV/0!)
  • Project-sheet hyperlinks resolve to existing tabs
ROUND 2 · CONTENT FIDELITY
independent reviewer subagent
  • Fresh general-purpose subagent
  • Gets OCR'd spec + populated workbook only
  • Compares every °F, ppm, %, GPM, CFM, time, schedule back to source
  • Flags any inferred behavior
  • Identifies spec sequences missing from the workbook
  • Reviewer never sees build code
Scripts scripts/qc_workbook.py references/qc-prompts.md
08
PHASE VI · DELIVERY

Save & Surface

Save to <Project>/0-Checklists/, then summarize the run for the user in concise prose. Don't list every test block — give them what they need to validate and move on.

Filename pattern: project folder name → spaces collapsed to underscores → _SOO_Verification.xlsx. e.g. "Murray City Public Works" → Murray_City_Public_Works_SOO_Verification.xlsx.

Summary covers:

  1. Equipment tabs created — count + names
  2. Total test blocks per tab
  3. Spec content explicitly excluded under the strict source rule, with the spec quote that triggered the exclusion
  4. Round 2 reviewer's flagged-missing items
  5. §3.4–3.6 startup/closeout content excluded as out-of-scope, with a note that it belongs in the Contractor Readiness checklist
  6. The computer:// link to the saved workbook
⚑ File lock detection
If the workbook is open in Excel during a re-save, cp and openpyxl.save both fail with Permission denied. Save to a sandbox scratch path first, then either ask the user to close Excel or save under a different filename. Don't lose the rebuilt content to a transient lock.
DELIVERABLE

SOO Verification Workbook

One .xlsx at <Project>/0-Checklists/: a Project header sheet with hyperlinked equipment index, plus one tab per equipment group containing every Mode / Operation / Task / Expected-result block that the spec mandates — strictly source-traceable, mechanically QC'd, and independently reviewed for content fidelity.

Primary output <ProjectName>_SOO_Verification.xlsx
Optional companions qc_round2_report.md   extraction_summary.md